package me.qingy.programmatic;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

/**
 * 经典 atoi() 题，注意范围越界处理
 *
 * @author qingy
 * @since 2021/8/26
 */
public class StrToInt {
    public int strToInt(String str) {
        char[] chars = str.toCharArray();
        int n = chars.length;

        // 是否为空
        if (n == 0) return 0;

        // 处理前置空格
        int i = 0;
        while (i < n && chars[i] == ' ') {
            i++;
        }
        // 全为空格
        if (i == n) return 0;

        // 处理符号
        int sign = 1;
        if (chars[i] == '-') {
            sign = -1;
            i++;
        } else if (chars[i] == '+') {
            i++;
        }

        int result = 0;
        int boundary = 214748364; // -2147483648~2147483647
        while (i < n && chars[i] >= '0' && chars[i] <= '9') {
            int d = chars[i] - '0';

            // 边界处理
            if (result > boundary) {
                if (sign == 1) return Integer.MAX_VALUE;
                else return Integer.MIN_VALUE;
            }
            if (result == boundary) {
                if (sign == 1 && d > 7) return Integer.MAX_VALUE;
                if (sign == -1 && d > 8) return Integer.MIN_VALUE;
            }

            result = result * 10 + d;
            i++;
        }
        return result * sign;
    }

    @Test
    public void testStrToInt() {
        Assertions.assertEquals(-42, strToInt("   -42"));
        Assertions.assertEquals(4193, strToInt("4193 with words"));
        Assertions.assertEquals(0, strToInt("words and 987"));
        Assertions.assertEquals(-2147483648, strToInt("-91283472332"));
    }
}
